{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## **演示0201：数组运算**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **案例1：数组与标量的运算**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**数组与标量运算，相当于数组中每个元素分别于该标量进行计算**  \n",
    ">* 建议尽量调用*numpy*中的函数。这些函数都支持以一维或多维数组作为参数；而*python*内建的运算函数有可能不支持数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1  2  4  8 16]\n",
      "[ 6  7  9 13 21]\n",
      "[ 5 10 20 40 80]\n",
      "[  1   4  16  64 256]\n",
      "[    2     4    16   256 65536]\n",
      "1024\n",
      "[0. 1. 2. 3. 4.]\n",
      "[[0. 1. 2.]\n",
      " [3. 4. 5.]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "a = np.array([1, 2, 4, 8, 16])\n",
    "print(a)\n",
    "print(a + 5)\n",
    "print(a * 5)\n",
    "print(a**2)    # 平方运算\n",
    "print(pow(2, a))    # 2的a次幂\n",
    "print(np.prod(a))    # 每个元素连乘\n",
    "print(np.log2(a))    # 以2为底的对数\n",
    "\n",
    "b = np.array([[1,2,4],[8,16,32]])\n",
    "print(np.log2(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **案例2：数组与数组的元素级运算**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**同维度数组之间的元素级运算**  \n",
    ">* 对应元素之间分别计算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 7  9 11 13 15]\n",
      "[ 6 14 24 36 50]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([1,2,3,4,5])\n",
    "b = np.array([6,7,8,9,10])\n",
    "print(a+b)\n",
    "print(a*b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 8 10 12]\n",
      " [14 16 18]]\n",
      "[[ 7 16 27]\n",
      " [40 55 72]]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[1,2,3],[4,5,6]])\n",
    "b = np.array([[7,8,9],[10,11,12]])\n",
    "print(a+b)\n",
    "print(a*b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**二维数组与一维数组之间的元素级运算**  \n",
    ">* 设*a*为$(M,N)$二维数组\n",
    "> * 若*b*为$(N,)$一维数组或$(1,N)$二维数组，则$a+b$成立($b+a$相同)。相当于*a*中的每一行，分别与b进行元素级操作\n",
    "> * 若*b*为$(K,)$一维数组($K \\neq N$)，则$a+b$不成立。因为*a*中的每一行，无法与*b*进行元素级操作\n",
    "> * 若*b*为$(M,1)$二维数组(列向量)，则$a+b$成立($b+a$相同)。相当于a中的每一列，分别与*b*进行元素级操作\n",
    "> * 若*b*为$(K,1)$二维数组($K \\neq M$)，则$a+b$不成立。因为*a*中的每一列，无法与*b*进行元素级操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[11 22 33 44 55]\n",
      " [16 27 38 49 60]\n",
      " [21 32 43 54 65]]\n",
      "[[11 12 13 14 15]\n",
      " [26 27 28 29 30]\n",
      " [41 42 43 44 45]]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]])\n",
    "b = np.array([10,20,30,40,50])\n",
    "c = np.array([[10],[20],[30]])\n",
    "print(a+b)\n",
    "print(a+c)\n",
    "\n",
    "e =np.array([10,20,30])\n",
    "# a+e    # 错误，每行元素数量不同\n",
    "f = np.array([[10],[20]])\n",
    "# a+f    # 错误，每列元素数量不同"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### **案例3：$*$操作符**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**$*$操作符始终进行元素级的乘法运算**  \n",
    ">* $a*b$与$b*a$具有相同的效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  4  9]\n",
      " [ 4 10 18]]\n",
      "[[ 1  2  3]\n",
      " [ 8 10 12]]\n",
      "[[ 1  2]\n",
      " [ 6  8]\n",
      " [15 18]]\n"
     ]
    }
   ],
   "source": [
    "# 二维数组与一维数组运算\n",
    "A = np.array([[1,2,3],[4,5,6]])\n",
    "a = np.array([1,2,3])\n",
    "b = np.array([[1],[2]])\n",
    "c = np.array([[1],[2],[3]])\n",
    "print(A*a)    # 正确，A中每一行分别与a进行元素级乘法运算。二者元素个数相同\n",
    "print(A*b)    # 正确，A中的每一行与b对应行进行元素级乘法运算。b中每行只有1个元素，相当于标量计算\n",
    "#print(A*c)    # 错误，A只有2行，但c有3行，因此c中最后一行数据找不到A中对应的数据进行计算\n",
    "\n",
    "B = np.array([[1,2],[3,4],[5,6]])\n",
    "#print(B*a)    # 错误，B每行只有2个元素，无法与a(每行3个元素)进行元素级运算\n",
    "#print(B*b)    # 错误，B有3行，但b只有2行，因此B的最后一行找不到对应的数据进行计算\n",
    "print(B*c)    # 正确，B中的每一行分别于c对应的每一行进行元素级乘法运算。c中每行只有1个元素，相当于标量计算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3]\n",
      " [2 4 6]]\n"
     ]
    }
   ],
   "source": [
    "# 一维数组之间的运算\n",
    "a = np.array([1,2,3])\n",
    "b = np.array([[1],[2]])\n",
    "c = np.array([1,2])\n",
    "d = np.array([[1,2],[3,4]])\n",
    "print(a*b)    # 正确，将a与b中每行分别进行元素级乘法运算。b中每行只有1个元素，相当于标量计算\n",
    "#print(a*c)    # 错误,a和c都是一维数组，但元素个数不同，无法进行元素级计算\n",
    "#print(a*d)    # 错误,a无法与d中的某一行进行元素级计算，因为它们元素个数不同"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">**行向量与列向量的$*$操作**  \n",
    ">* 维度为$(N,)$的一维数组(行向量)*a*与维度为$(M,1)$的列向量*b*进行元素级运算，得到$(N,M)$二维数组\n",
    ">* 相当于用*a*与*b*的每行(仅有1个元素)进行元素级乘法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3  4  5]\n",
      " [ 2  4  6  8 10]\n",
      " [ 3  6  9 12 15]]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([1,2,3,4,5])    #(5)\n",
    "b = np.array([[1],[2],[3]])    # (3, 1)\n",
    "print(a*b)    # (5,3)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
